/*
 * @Author: Jiarun
 * @Date: 2021-06-01 15:56:27
 * @LastEditors: Jiarun
 * @LastEditTime: 2021-06-07 20:37:13
 * @Description: 
 */
#include "es_uart.h"
#include <stdarg.h>

/**
 * @description: 串口配置初始化
 * @param {USART_TypeDef} *	使用的串口
 * @param {u32} bound		波特率
 * @param {va} ...			可变参数: 不开中断写 pass | 开中断则写 两个中断优先级
 * @return None
 * @Sample uart_init(USART1, 115200, pass);	//串口1初始化且不开中断
 * @Sample uart_init(USART2, 115200, 1, 2);	//串口2初始化, 中断抢占优先级为 1, 响应优先级为 2;
 */
void uart_init(USART_TypeDef * uart, u32 bound, ...)
{
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	va_list ap;
	GPIO_TypeDef* GPIOx;
	uint32_t RCC_APBPeriphClock;
	uint16_t Tx_Pin;
	uint8_t IRQChannel, Preemption, Sub;
	
	switch ((uint32_t)uart)
	{
	case (uint32_t)USART1:
			RCC_APBPeriphClock = RCC_APB2Periph_USART1;
			GPIOx = GPIOA;
			Tx_Pin = GPIO_Pin_9;
			break;

	case (uint32_t)USART2:
			RCC_APBPeriphClock = RCC_APB1Periph_USART2;
			GPIOx = GPIOA;
			Tx_Pin = GPIO_Pin_2;
			break;	
	
	case (uint32_t)USART3:
			RCC_APBPeriphClock = RCC_APB1Periph_USART3;
			GPIOx = GPIOB;
			Tx_Pin = GPIO_Pin_10;
			break;	
	
	default:
			break;
	}
	
	/*** 只有 USART1 连接 APB2 使用 PCLK2 (最大72MHz)，其它USART使用PCLK1(最大36MHz) ***/
	if(RCC_APBPeriphClock == RCC_APB2Periph_USART1)
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	else
		RCC_APB1PeriphClockCmd(RCC_APBPeriphClock, ENABLE);
	
	//uart_tx
	gpio_init(GPIOx, Tx_Pin, GPIO_Mode_AF_PP);
	//uart_rx
  gpio_init(GPIOx, Tx_Pin << 1, GPIO_Mode_IN_FLOATING); 
	

	va_start(ap, bound);
	Preemption = va_arg(ap, int);	

	if(Preemption & 0x80){
		/* 不开启中断，略过中断配置 */
	}else{
		
		Sub = va_arg(ap, int);
		
		switch ((uint32_t)uart)
		{
		case (uint32_t)USART1:
				IRQChannel = USART1_IRQn;
				break;
		
		case (uint32_t)USART2:
				IRQChannel = USART2_IRQn;
				break;		
		
		case (uint32_t)USART3:
				IRQChannel = USART3_IRQn;
				break;

		default:
				break;
		}/*end switch*/
		
		//Usart NVIC 中断配置
		NVIC_InitStructure.NVIC_IRQChannel = IRQChannel;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= Preemption ;
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = Sub;		
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
		NVIC_Init(&NVIC_InitStructure);
		USART_ITConfig(uart, USART_IT_RXNE, ENABLE);//使能中断
	}/*end if*/
	va_end(ap);
	
	//USART 配置
	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	

  USART_Init(uart, &USART_InitStructure);
  USART_Cmd(uart, ENABLE);
}
